package wechat

import (
	"errors"
	"fmt"
	"net/http"
	"regexp"
	"sync"
	"time"
	configswechat "wechat/src/configs/wechat"
	modelwechat "wechat/src/model/wechat"
	"wechat/src/tools"
)

// WechatLogin 微信树
type WechatLogin struct {
	Uuid string `json:"uuid"`
}

func Auth(wgp *sync.WaitGroup, statusTube chan string) {
	wechat := new(WechatLogin)

	//获取uuid
	if err := wechat.jsLogin(); err != nil {
		panic(err)
	}
	//监听状态
	wgp.Add(1)
	go wechat.listenIn(wgp, statusTube)

	//绘制二维码
	if err := wechat.drawQrcode(); err != nil {
		panic(err)
	}
}

func (w *WechatLogin) listenIn(wgp *sync.WaitGroup, statusTube chan string) {
	defer wgp.Done()

	defer func() {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()

	//var chans = make([]byte, 1)
	for {
		code, body, err := w.mmwebwxLogin()
		if err != nil {
			panic(err)
		}
		switch code {
		case "408":
			fmt.Println("请扫描")
		case "400":
			//需要重新获取
			fmt.Println("二维码已过期")
			if err = w.jsLogin(); err != nil {
				panic(err)
			}
			if err = w.drawQrcode(); err != nil {
				panic(err)
			}
		case "201":
			fmt.Println("手机端已扫码，待确认")
		case "200":
			//登录成功
			fmt.Println("已确认登录")
			reg := regexp.MustCompile(`window.redirect_uri="(\S+)";`)
			matches := reg.FindStringSubmatch(string(body))
			if len(matches) != 2 {
				panic(errors.New("登录监听登录回调失败-正则匹配失败"))
			}
			statusTube <- matches[1]
			goto succeeded
		}
		//加一个额外延迟-以防请求过快导致频繁请求
		time.Sleep(5 * time.Second)
	}
succeeded:
}

func (w WechatLogin) mmwebwxLogin() (string, []byte, error) {
	body, _, err := tools.Get(configswechat.MmwebwxLogin, modelwechat.MmwebwxLoginNewConfig(w.Uuid), nil, w.loginClient())
	if err != nil {
		return "", nil, err
	}
	reg := regexp.MustCompile(`^window.code=(\d+);`)
	submatch := reg.FindStringSubmatch(string(body))
	if len(submatch) != 2 {
		return "", nil, errors.New(fmt.Sprintf("获取登录状态-正则取值失败"))
	}

	return submatch[1], body, nil
}

func (t WechatLogin) drawQrcode() error {
	if err := tools.DrawQrcode(configswechat.Qrcode + t.Uuid); err != nil {
		return err
	}
	return nil
}

func (w *WechatLogin) jsLogin() error {
	body, _, err := tools.Get(configswechat.JsLogin, *modelwechat.JsLoginNewConfig(), nil, w.loginClient())
	if err != nil {
		return errors.New(fmt.Sprintf("获取UUID失败-GET请求失败：%v", err))
	}
	reg := regexp.MustCompile(`^window.QRLogin.code = (\d+); window.QRLogin.uuid = "(\S+)";$`)
	submatchs := reg.FindStringSubmatch(string(body))
	if len(submatchs) != 3 {
		return errors.New("获取UUID失败-正则取值失败")
	}
	if submatchs[1] != "200" {
		return errors.New(fmt.Sprintf("获取UUID失败-请求内容返回状态为%v", submatchs[1]))
	}
	w.Uuid = submatchs[2]
	return nil
}

func (w WechatLogin) loginClient() *http.Client {
	client := &http.Client{
		Timeout: 180 * time.Second,
	}
	return client
}
